# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from EssaiAVA.ava.models import *
from django.http import HttpResponseRedirect, Http404
from django.forms.formsets import formset_factory
from django.core.mail import send_mail
from EssaiAVA.ava.outils.message import *
from EssaiAVA.ava.outils.geocode import *
from EssaiAVA.ava.outils.manage_DB import *
from EssaiAVA.ava.outils.optimisation import *
from EssaiAVA.ava.outils.optimisation_restaurant import *
from django.core.exceptions import ValidationError
from django.utils.functional import curry
from multiprocessing import Process
from django.utils.translation import ugettext as _

def index(request):
    return render_to_response('index.html', 
                              context_instance=RequestContext(request)
                              )

def mentions_legales(request):
    return render_to_response('mentions_legales.html', 
                              context_instance=RequestContext(request)
                              )

def organisation(request, tag):
    if tag=='restau' :
        if request.method == 'POST': 
            form1 = OrganisationForm(request.POST)
            form2 = InvitationForm(request.POST)
            if form1.is_valid() and form2.is_valid():
                nom_orga = form1.cleaned_data['nom_orga']
                prenom_orga = form1.cleaned_data['prenom_orga']
                email_orga = form1.cleaned_data['email_orga']
                date = form2.cleaned_data['date']
                heure = form2.cleaned_data['heure']
                invitation = Invitation(date=date, heure=heure)
                invitation.save()
                organisateur = Invite(nom=nom_orga, prenom=prenom_orga, 
                                  email=email_orga, presence=True, invit=invitation, confirm=True, lang=request.LANGUAGE_CODE)
                organisateur.save()
                return HttpResponseRedirect('/restau/%s/qui_inviter/' % invitation.id) 
        else:
            form1 = OrganisationForm()
            form2 = InvitationForm()
            return render_to_response('organisation_restau.html',
                              {'form1': form1, 'form2': form2},
                              context_instance=RequestContext(request))
    else:
        if request.method == 'POST': 
            form1 = OrganisationForm(request.POST)
            if form1.is_valid(): 
                nom_orga = form1.cleaned_data['nom_orga']
                prenom_orga = form1.cleaned_data['prenom_orga']
                email_orga = form1.cleaned_data['email_orga']
                invit = Invitation()
                invit.save()
                organisateur = Invite(nom=nom_orga, prenom=prenom_orga, 
                                  email=email_orga, presence=True, invit=invit, lang=request.LANGUAGE_CODE)
                organisateur.save()
                return HttpResponseRedirect('/sondage/%s/qui_inviter/' % invit.id) 
        else:
            form1 = OrganisationForm()
            return render_to_response('organisation_sondage.html',
                              {'form1': form1},
                              context_instance=RequestContext(request))
    

def qui_inviter(request, invit_id, tag):
    invit = get_object_or_404(Invitation, id=invit_id)
    InviteFormSet = formset_factory(InviteForm)
    if tag=='restau':
        if request.method == 'POST': 
            formset = InviteFormSet(request.POST, request.FILES)
            form_lang = LangueForm(request.POST)
            if formset.is_valid() and form_lang.is_valid():
                lang=form_lang.cleaned_data['lang']
                for form in formset.forms:
                    email_invite = form.cleaned_data['email_invite']
                    invite = Invite(email=email_invite, invit=invit,
                                    presence=False, lang=lang)
                    invite.save()
                return HttpResponseRedirect('/{}/{}/custom/'.format(tag, invit_id))
        else:
            formset = InviteFormSet()
            form_lang = LangueForm()
        return render_to_response('qui_inviter_restau.html', {'formset': formset, "form_lang":form_lang},
                                  context_instance=RequestContext(request))
    else:
        if request.method == 'POST': 
            formset = InviteFormSet(request.POST, request.FILES)
            form_lang = LangueForm(request.POST)
            if formset.is_valid() and form_lang.is_valid():
                lang=form_lang.cleaned_data['lang']
                for form in formset.forms:
                    email_invite = form.cleaned_data['email_invite']
                    invite = Invite(email=email_invite, invit=invit,
                                    presence=False, lang=lang)
                    invite.save()
                return HttpResponseRedirect('/{}/{}/custom/'.format(tag, invit_id))
        else:
            formset = InviteFormSet()
            form_lang = LangueForm()
        return render_to_response('qui_inviter_sondage.html', {'formset': formset, "form_lang":form_lang},
                                  context_instance=RequestContext(request))
    
def custom(request, invit_id, tag):
    invit =  get_object_or_404(Invitation,id=invit_id)
    if tag=='restau':
        if request.method == 'POST':
            form_quest = MultiRepForm(request.POST)
            form_restau = SelectCritereForm(request.POST)
            if form_quest.is_valid() and form_restau.is_valid():
                type_restau = form_restau.cleaned_data['type_restaurant']
                budget = form_restau.cleaned_data['budget']
                distance = form_restau.cleaned_data['distance']
                question = Question(champ='Type de restaurant', invit=invit)
                question.save()
                question = Question(champ='Budget', invit=invit)
                question.save()
                question = Question(champ='Distance', invit=invit)
                question.save()
#                if type_restau or budget or distance :
#                    if type_restau:
#                        question = Question(champ='Type de restaurant', invit=invit)
#                        question.save()
#                    if budget:
#                        question = Question(champ='Budget', invit=invit)
#                        question.save()
#                    if distance:
#                        question = Question(champ='Distance', invit=invit)
#                        question.save()
#                else:
#                    raise ValidationError('Veuillez selectionner au moins un critère')
                champ = form_quest.cleaned_data['question']
                if champ != '':
                    question = Question(champ=champ, invit=invit)
                    question.save()
                    rep = form_quest.cleaned_data['reponses']
                    list_rep =  rep.splitlines()
                    for rep in list_rep:
                        reponse = Reponse(champ=str(rep), question=question)   
                        reponse.save()
                invit.dict = set_dict(invit)
                invit.save()
                invites_list = invit.invite_set.all()
                for invite in invites_list[1:]:
                    send_mail(_(u"Invitation OPTAMI"),
                              message_invitation_restaurant(invit, invite.id),
                              "invitation.ava@gmail.com",
                              [str(invite.email)],
                              fail_silently=False)
                send_mail(_(u"Votre invitation OPTAMI"),
                                  message_organisateur_restaurant(invit, invit.invite_set.all()[0].id),
                                  "invitation.ava@gmail.com",
                                  [invit.invite_set.all()[0].email],
                                  fail_silently=False)            
                return HttpResponseRedirect('/{}/{}/ok_orga/'.format(tag, invit_id))
        else:
            form_quest = MultiRepForm()
            form_restau = SelectCritereForm()
        return render_to_response('custom_restau.html', {'form_quest' : form_quest,
                                                  'form_restau': form_restau},
                                  context_instance=RequestContext(request))
    else:
        ReponseFormSet = formset_factory(MultiRepForm)
        if request.method == 'POST':
            formset= ReponseFormSet(request.POST, request.FILES)
            if formset.is_valid():
                for form in formset.forms:
                    champ = form.cleaned_data['question']
                    question = Question(champ=champ, invit=invit)
                    question.save()
                    rep = form.cleaned_data['reponses']
                    list_rep =  rep.splitlines()
                    for rep in list_rep:
                        reponse = Reponse(champ=str(rep), question=question)   
                        reponse.save()
                invit.dict = set_dict(invit)
                invit.save()
                invites_list = invit.invite_set.all()
                for invite in invites_list[1:]:
                    send_mail(_(u"Invitation OPTAMI"),
                              message_invitation_sondage(invit, invite.id),
                              "invitation.ava@gmail.com",
                              [str(invite.email)],
                              fail_silently=False)
                send_mail(_("Votre invitation OPTAMI"),
                                  message_organisateur_sondage(invit, invit.invite_set.all()[0].id),
                                  "invitation.ava@gmail.com",
                                  [invit.invite_set.all()[0].email],
                                  fail_silently=False)                            
                return HttpResponseRedirect('/{}/{}/ok_orga/'.format(tag, invit_id))
        else:
            formset= ReponseFormSet()
            return render_to_response('custom_sondage.html', {'formset': formset},
                                  context_instance=RequestContext(request))
        
        

def ok_orga(request, invit_id, tag):
    invit = get_object_or_404(Invitation, id=invit_id)
    if tag=='restau':
        return render_to_response('ok_orga_restau.html',
                              {'invites_list':invit.invite_set.all()[1:],
                               'lien':'/{}/{}/choix/{}/'.format(tag, invit_id,
                                                            invit.invite_set.all()[0].id)}, 
                              context_instance=RequestContext(request)
                              )
    else:
        return render_to_response('ok_orga_sondage.html',
                              {'invites_list':invit.invite_set.all(),
                               'lien':'/{}/{}/choix/{}/'.format(tag, invit_id,
                                                            invit.invite_set.all()[0].id)}, 
                              context_instance=RequestContext(request)
                              )
        

def choix(request, invit_id, invite_id, tag):
    invit = get_object_or_404(Invitation, id=invit_id)
    invite = get_object_or_404(Invite, id=invite_id)
    orga = invit.invite_set.all()[0]
    if tag=='restau':
        formset_choice = formset_factory(ChoiceForm, extra=0)
        formset_choice.form = staticmethod(curry(ChoiceForm, invit=invit))
        if request.method == 'POST':
            if invite.coord:
                c = invite.coord
                c.delete()
            if invite.critere_set.all():
                for crit in invite.critere_set.all():
                    crit.delete()
            formset = formset_choice(request.POST, request.FILES)
            form2 = AdresseForm(request.POST)
            if formset.is_valid() and form2.is_valid():
                for form in formset.forms:
                    type = form.cleaned_data['type']
                    nbre_etoile = form.cleaned_data['nbre_etoile']
                    choix = Critere(type=type, nbre_etoile=nbre_etoile, invite=invite)
                    choix.save()
                    detail = form.cleaned_data['detail']
                    sous_critere = Detail(detail=detail, critere=choix)
                    sous_critere.save()
                adresse = form2.cleaned_data['adresse']
                adresse_formatee = format_adresse(adresse)
                G = geocode(adresse_formatee)
                if G==False:
                    raise ValidationError('Adresse incorrecte')
                else:
                    coord = Coordonnees(longitude=G[1], latitude=G[0], adresse=adresse)
                    coord.save()
                    invite.coord = coord
                    invite.presence = True
                    invite.save()
                    if str(orga.id) == str(invite_id):
                        pass
                    else:
                        send_mail(_(u"Invitation OPTAMI : une personne a répondu !"),
                                    message_information_restaurant(invit, invite, orga.id),
                                    "invitation.ava@gmail.com",
                                    [invit.invite_set.all()[0].email],
                                    fail_silently=False)
                        send_mail(_(u"Invitation OPTAMI"),
                                    message_invite_restaurant(invit, invite),
                                    "invitation.ava@gmail.com",
                                    [invite.email],
                                    fail_silently=False)
                return HttpResponseRedirect('/{}/{}/ok_choix/{}/'.format(tag, str(invit_id), str(invite_id)))
        else:
            if invite.critere_set.all():
                initial = []
                for crit in invite.critere_set.all():
                    initial.append({'type': crit.type, 'detail': crit.detail_set.all()[0].detail, "nbre_etoile": str(crit.nbre_etoile)})
                formset = formset_choice(initial=initial)        
            else:
                formset = formset_choice(initial=[{'type':'GO', 'detail':'AS', 'nbre_etoile':'4'}, {'type':'DI', 'detail':'ML', 'nbre_etoile':'3'}, {'type':'BU', 'detail':'MC', 'nbre_etoile':'4'} ])
            if invite.coord:
                form2 = AdresseForm(adr=invite.coord.adresse)
            else:
                form2 = AdresseForm()
            return render_to_response('choix_restau.html', {'formset':formset, 'form2':form2, 'invit_id': invit_id},
                              context_instance=RequestContext(request))
    else:
        formset_choice = formset_factory(ChoiceForm, extra=0)
        formset_choice.form = staticmethod(curry(ChoiceForm, invit=invit))
        if request.method == 'POST':
            if invite.critere_set.all():
                for crit in invite.critere_set.all():
                    crit.delete()
            formset = formset_choice(request.POST, request.FILES)
            if formset.is_valid():
                for form in formset.forms:
                    type = form.cleaned_data['type']
                    nbre_etoile = form.cleaned_data['nbre_etoile']
                    choix = Critere(type=type, nbre_etoile=nbre_etoile, invite=invite)
                    choix.save()
                    detail = form.cleaned_data['detail']
                    sous_critere = Detail(detail=detail, critere=choix)
                    sous_critere.save()
                invite.presence = True
                invite.save()
                if str(orga.id) == str(invite_id):
                    pass
                else:
                    send_mail(_(u"Invitation OPTAMI : une personne a répondu !"),
                                    message_information_sondage(invit, invite, orga.id),
                                    "invitation.ava@gmail.com",
                                    [invit.invite_set.all()[0].email],
                                    fail_silently=False)
                    send_mail(_("Invitation OPTAMI"),
                                    message_invite_sondage(invit, invite),
                                    "invitation.ava@gmail.com",
                                    [invite.email],
                                    fail_silently=False)
                return HttpResponseRedirect('/{}/{}/ok_choix/{}/'.format(tag, str(invit_id), str(invite_id)))
        else:
            if invite.critere_set.all():
                initial = []
                for crit in invite.critere_set.all():
                    initial.append({'type': crit.type, 'detail': crit.detail_set.all()[0].detail, "nbre_etoile": str(crit.nbre_etoile)})
                formset = formset_choice(initial=initial)        
            else:
                formset = formset_choice(initial=[{'type':'CU0', 'detail':'CU0R0', 'nbre_etoile':'2'}])
            return render_to_response('choix_sondage.html', {'formset':formset, 'invit_id': invit_id},
                              context_instance=RequestContext(request))

def ok_choix(request, invit_id, invite_id, tag):
    invit = get_object_or_404(Invitation, id=invit_id)
    orga = invit.invite_set.all()[0]
    orga_ok = (str(orga.id) == str(invite_id))
    if tag=='restau':
        if orga_ok :
            return render_to_response('ok_choix_restau.html',
                                  {'cloture':_(u"Lorsque vous aurez reçu suffisamment de réponses, vous pourrez clôturer le vote"),
                                   'invit_id': invit_id,
                                   'invite_id' : invite_id,
                                   'orga_ok':orga_ok,
                                   'tag':tag}, 
                                  context_instance=RequestContext(request)
                                  )        
        else:
            return render_to_response('ok_choix_restau.html',
                                  {'contact':_(u"Vous pouvez contacter l'organisateur de l'invitation"),
                                   'adresse':_(u"avec l'adresse :"),
                                   'organisateur_email':orga.email,
                                   'organisateur_prenom':orga.prenom,
                                   'organisateur_nom':orga.nom,
                                   'ulterieur':_(u"Vous recevrez ultérieurement le lieu du rendez-vous")}, 
                                  context_instance=RequestContext(request)
                                  )    
    else:
        if orga_ok :
            return render_to_response('ok_choix_sondage.html',
                                  {'cloture':_(u"Lorsque vous aurez reçu suffisamment de réponses, vous pourrez clôturer le vote"),
                                   'invit_id': invit_id,
                                   'invite_id' : invite_id,
                                   'orga_ok':orga_ok,
                                   'tag':tag}, 
                                  context_instance=RequestContext(request)
                                  )        
        else:
            return render_to_response('ok_choix_sondage.html',
                                  {'contact':_(u"Vous pouvez contacter l'organisateur du sondage"),
                                   'adresse':_(u"avec l'adresse :"),
                                   'organisateur_email':orga.email,
                                   'organisateur_prenom':orga.prenom,
                                   'organisateur_nom':orga.nom}, 
                                  context_instance=RequestContext(request)
                                  )    
        
        
def manage(request, invit_id, invite_id, tag):
    invit = get_object_or_404(Invitation, id=invit_id)
    orga = invit.invite_set.all()[0]
    invite = Invite.objects.get(id=invite_id)
    choices_list = invite.critere_set.all()
    rep_list = []
    dict = eval(invit.dict)
    for choice in choices_list :
        rep_list.append((_(dict[str(choice.type)]) +' : ' + _(dict[str(choice.detail_set.all()[0].detail)]), choice.nbre_etoile))
    if tag == 'restau':
        lien = "http://127.0.0.1:8000/restau/{}/choix/{}".format(str(invit.id), str(invite.id))
        if str(orga.id)==str(invite_id):
            if request.method == 'POST':
                methode = Methode(Optimisation_Restaurant)
                p = Process(target=methode.optimiser, args=(invit,))
                p.start()
                return HttpResponseRedirect('/restau/{}/latence/'.format(str(invit_id)))
            else:
                return render_to_response('manage_orga_restau.html',
                                      {'invites_list':invit.invite_set.all(),
                                       'invit_id':invit.id,
                                       'rep_list' : rep_list,
                                       'lien' : lien},
                                       context_instance=RequestContext(request))
        else:
            return render_to_response('manage_invite_restau.html',
                                      {'invites_list':invit.invite_set.all(),
                                       'invit_id':invit.id,
                                       'rep_list' : rep_list,
                                       'lien' : lien},
                                       context_instance=RequestContext(request))
    else:
        lien = "http://127.0.0.1:8000/sondage/{}/choix/{}".format(str(invit.id), str(invite.id))
        if request.method == 'POST':
            invites_list=[]
            for j in invit.invite_set.all():
                if j.presence:
                    invites_list.append(j)
            tous_les_choix = []
            dict = eval(invit.dict)
            for inv in invites_list:
                choices_list = inv.critere_set.all()
                rep_list = []
                for choice in choices_list :
                    rep_list.append((_(dict[str(choice.type)]) +' : ' + _(dict[str(choice.detail_set.all()[0].detail)]), choice.nbre_etoile))   
                tous_les_choix.append([inv.email,rep_list])
            return render_to_response('resultat_sondage.html',
                                          {'tous_les_choix' : tous_les_choix}, 
                                      context_instance=RequestContext(request)
                                          )
        else:
            if str(orga.id)==str(invite_id):
                return render_to_response('manage_orga_sondage.html',
                                  {'invites_list':invit.invite_set.all(),
                                       'invit_id':invit.id,
                                       'rep_list' : rep_list,
                                       'lien' : lien},
                                   context_instance=RequestContext(request))
            else:
                return render_to_response('manage_invite_sondage.html',
                                      {'invites_list':invit.invite_set.all(),
                                       'invit_id':invit.id,
                                       'rep_list' : rep_list,
                                       'lien' : lien},
                                       context_instance=RequestContext(request))

def latence(request, invit_id, tag):
    return render_to_response('latence.html', context_instance=RequestContext(request))
   

def resultat_restau(request, invit_id, invite_id):
    if request.method == 'POST':
        cleanup(invit_id)
        return render_to_response('cloture.html',
                                  context_instance=RequestContext(request))
    else:
        invit = get_object_or_404(Invitation, id=invit_id)
        invite = get_object_or_404(Invite, id=invite_id)
        orga = invit.invite_set.all()[0]
        orga_ok = (str(orga.id) == str(invite_id))
        restau = invit.restaurant_set.get(choisi=True)
        pas_confirme = not invite.confirm
        g = format_coordonnees(restau.coord.latitude,
                           restau.coord.longitude)
        i = format_coordonnees(Invite.objects.get(id=invite_id).coord.latitude,
                           Invite.objects.get(id=invite_id).coord.longitude)
        invites_list = []
        for j in invit.invite_set.all():
            if j.presence:
                invites_list.append(j)
        tous_les_choix = []
        dict = eval(invit.dict)
        for inv in invites_list:
            choices_list = inv.critere_set.all()
            rep_list = []
            for choice in choices_list :
                rep_list.append((_(dict[str(choice.type)]) +' : ' + _(dict[str(choice.detail_set.all()[0].detail)]), choice.nbre_etoile))   
            tous_les_choix.append([inv.email,rep_list])
        return render_to_response('resultat_restau.html',
                                  {'barycentre_latitude': g[0],
                                   'barycentre_longitude': g[1],
                                   'invite_latitude': i[0],
                                   'invite_longitude': i[1],
                                   'restaurant_nom': restau.nom,
                                   'url': restau.url,
                                   'orga_ok':orga_ok,
                                   'pas_confirme':pas_confirme,
                                   'invit_id':invit_id,
                                   'email': invite.email,
                                   'tous_les_choix' : tous_les_choix,
                                  }, 
                              context_instance=RequestContext(request)
                                  )
